package com.sys.dispatch;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.sys.db.dao.DefFlowDao;
import com.sys.db.dao.DefJobDao;
import com.sys.db.dao.DefJobTypeDao;
import com.sys.db.dao.DefJobTypeParaDao;
import com.sys.db.dao.LogFlowDao;
import com.sys.db.dao.LogJobDao;
import com.sys.db.dao.RunFlowJobDao;
import com.sys.db.dao.RunJobParaDao;
import com.sys.db.util.ExtendDate;
import com.sys.db.util.GetBeanUtil;
import com.sys.pojo.DefFlow;
import com.sys.pojo.DefJob;
import com.sys.pojo.DefJobType;
import com.sys.pojo.DefJobTypePara;
import com.sys.pojo.LogJob;
import com.sys.pojo.RunFlowJob;
import com.sys.pojo.RunFlowJobPara;
import com.sys.pojo.RunJobPara;

public class DispatchUtil {
	protected static Logger log = Logger.getLogger(DispatchUtil.class);
	/**
	 * 判断该作业流包含的作业是否存在其他作业流中，存在且正在运行的返回true
	 * @return
	 */
	public boolean jobFromFlowIsRun(DefFlow defFlow)throws Exception{
		if(defFlow == null || defFlow.getFlowId()==null){
			return false;
		}
		RunFlowJobDao runFlowJobDao=(RunFlowJobDao) GetBeanUtil.getDao("runFlowJobDaoImpl");//作业流、作业关系dao
		DefFlowDao defDao=(DefFlowDao) GetBeanUtil.getDao("defFlowDaoImpl");//作业流dao
		List rfjList=runFlowJobDao.findByFlowId(new Integer(defFlow.getFlowId()));//查找作业流包含的作业
		if(rfjList==null||rfjList.size()==0){
			throw new ExpServiceException("作业流["+defFlow.getFlowName()+"]没有作业，请维护！");
		}else{
			List rList=null;
			for(int i=0;i<rfjList.size();i++){
				RunFlowJobPara rfj=(RunFlowJobPara) rfjList.get(i);
				rList=runFlowJobDao.findByJobId(new Integer(rfj.getJobId()),new Integer(defFlow.getFlowId()));//查询作业在其他作业流集合
				if(rList!=null&&rList.size()>0){
					for(int j=0;j<rList.size();j++){
						RunFlowJob rr=(RunFlowJob) rList.get(j);
						DefFlow de=null;
						de=defDao.findById(new Integer(rr.getFlowId()));
						if(de!=null&&"1".equals(de.getStatus())){//判断作业所在作业流是否正在运行
							System.out.println("运行的作业流包含的作业正在其他作业流中运行！");
							return true;
						}
					}
				}
			}
		}
		return false;
	}
	/**
	 * 查找作业流包含的作业
	 * @param flowId
	 * @return
	 * @throws Exception
	 */
	public List getJobFromFlow(int flowId)throws Exception{
		RunFlowJobDao runFlowJobDao=(RunFlowJobDao) GetBeanUtil.getDao("runFlowJobDaoImpl");//作业流、作业关系dao
		List list=runFlowJobDao.findByFlowId(flowId);
		return list;
	}
	public void exeJobOfFlow(DefFlow defFlow)throws Exception{
		DefJobDao defJobDao= (DefJobDao) GetBeanUtil.getDao("defJobDaoImpl");//作业dao
		DefJobTypeDao defJobTypeDao= (DefJobTypeDao) GetBeanUtil.getDao("defJobTypeDaoImpl");//作业类型dao
		DefJobTypeParaDao defJobTypeParaDao= (DefJobTypeParaDao) GetBeanUtil.getDao("defJobTypeParaDaoImpl");//作业参数dao
		RunJobParaDao runJobParaDao=(RunJobParaDao) GetBeanUtil.getDao("runJobParaDaoImpl");//作业参数值dao
		LogJobDao logJobDao=(LogJobDao) GetBeanUtil.getDao("logJobDaoImpl");//作业流日志dao
		List rfjList=getJobFromFlow(new Integer(defFlow.getFlowId()));//该作业流包含的作业list
		log.info("作业流["+defFlow.getFlowName()+"]包含"+(rfjList==null?0:rfjList.size())+"条作业");
		for(int i=0;i<rfjList.size();i++){
			RunFlowJobPara rfj=(RunFlowJobPara) rfjList.get(i);
			DefJob dj=defJobDao.findById(new Integer(rfj.getJobId()));
			if(dj.getJobType()!=null&&!"".equals(dj.getJobType())){
				log.info("查询作业["+dj.getJobName()+"]包含的参数和对应值");
				DefJobType djt=defJobTypeDao.findById(new Integer(dj.getJobType()));//作业类型
				if(djt==null){
					throw new ExpServiceException("作业["+dj.getJobName()+"]没有维护作业类型！");
				}
				List list=defJobTypeParaDao.findByTypeId(new Integer(dj.getJobType()));
				if(list==null||list.size()==0){
					throw new ExpServiceException("作业类型["+djt.getJobTypeName()+"]没有维护参数！");
				}else{
					List valueList=runJobParaDao.findByJobId(new Integer(rfj.getJobId()));
					if(valueList.size()!=list.size()){
						throw new ExpServiceException("作业["+dj.getJobName()+"]参数维护有错误");
					}
					StringBuffer sb=new StringBuffer();//组装执行程序的路径和参数
					String datadate=getDataDate(defFlow);
					sb.append(djt.getProgramPath()+djt.getProgramName()+" "+datadate);
					for(int j=0;j<list.size();j++){
						DefJobTypePara a=(DefJobTypePara) list.get(j);
						RunJobPara b=runJobParaDao.findByTypeParaId(a.getId(),dj.getJobId());
						sb.append(" "+b.getJobParaValue());
					}
					log.info("调用后台程序命令："+sb.toString());
					if("BAT".equals(djt.getProgramType())){
						log.info("BAT程序开始运行");
						LogJob lj=new LogJob();
						lj.setDataDate(datadate);
						lj.setFlowId(defFlow.getFlowId());
						lj.setJobId(dj.getJobId());
						lj.setRunSTime(ExtendDate.getSysDate());
						logJobDao.save(lj);
						JavaExeMethod jem=new JavaExeMethod();
						boolean workFlag=jem.exeBat(sb.toString());
						log.info("执行结果："+workFlag);
						if(workFlag){
							//记录作业执行日志
							lj.setRunETime(ExtendDate.getSysDate());
							logJobDao.update(lj);
						}else{
							lj.setRunETime(ExtendDate.getSysDate());
							lj.setErrTxt("作业["+dj.getJobName()+"]执行失败");
							//记录作业错误日志
							logJobDao.update(lj);
							throw new ExpServiceException("作业["+dj.getJobName()+"]执行失败");
						}
					}
				}
			}else{
				throw new ExpServiceException("作业["+rfj.getJobName()+"]不存在！");
			}
			log.info("作业["+rfj.getJobName()+"]执行结束");
		}
	}
	/**
	 * 校验依赖的工作流状态
	 * @param def
	 * @return
	 */
	public boolean validateStatus(DefFlow def) throws Exception{
		String dateS=getDataDate(def);
		LogFlowDao lfDao=(LogFlowDao) GetBeanUtil.getDao("logFlowDaoImpl");
		List list=null;
		list=lfDao.findByIdDateSuccess(def.getFlowId(), dateS);
		if(list==null||list.size()==0){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 得到应该跑的数据日期
	 * @param def
	 * @return
	 */
	public String getDataDate(DefFlow def){
		String sysTime=ExtendDate.getStringDonversionDate(new Date());
		int year=new Integer(sysTime.split("-")[0]);
		String type=def.getFreType();//运行类型
		String dateS="";//应该跑的数据日期
		if("D".equals(type)){
			dateS=ExtendDate.getControlDateAheadTimeString(sysTime,-1);
		}else if("M".equals(type)){
			dateS=ExtendDate.getAheadMonthEndDate(sysTime, -1);
		}else if("S".equals(type)){
			dateS=ExtendDate.getAheadSeasonEndDate(sysTime,-1);
		}else if("Y".equals(type)){
			dateS=(year-1)+"1231";
		}
		return dateS;
	}
	/**
	 * 得到平均运行时间
	 * @param def
	 * @return
	 */
	public long getAvgTimes(DefFlow def,String startTime) throws Exception{
		if(def!=null&&startTime!=null){
			long runTime=ExtendDate.getTimeDifferenceSecond(startTime, ExtendDate.getSysDate());
			long avgtime=(def.getAvgRun()*def.getRuntimes()+runTime)/((def.getRuntimes()+1));
			return avgtime;
		}else{
			
			return 0;
		}
	}
}
